--
-- Author: ping.wang
-- Date: 2018-11-21 10:57:38
--
local DBMMgr = class("DBMMgr")
local Skill_id = battle.Skill.id
local Skill_targetId = battle.Skill.targetId
local Skill_getIsMarkTarget = battle.Skill.getIsMarkTarget
local string_split = string.split
local OPEN_ANI_NAME = "open"
local CLOSE_ANI_NAME = "close"
local STAY_TIME = 3
--初始化的时候需要传入父节点
function DBMMgr:ctor()
	self:clear()
end

function DBMMgr:setRootNode(rootNode)
	self._rootNode = rootNode
end

local TipsTimeEnum = {
	BattleStart = 1, --战斗开始时候
	SingSkill = 2, --吟唱技能开始时候
	InSkill = 3, --受到技能影响
	InBuff = 4, --受到BUFF影响
	Hp = 5, --指定怪物血量达到参数值
}

function DBMMgr:clear()
    if self._cronsIdx then
        scheduler.cancelCron(self._cronsIdx)
        self._cronsIdx = nil
    end

	self._dbmCDTabel = {} --存放dbm播放的上次播放时间
	self._curBattleDBMs = {}
	self:removeTips()
	self._rootNode = nil
	self._myUnitId = 0
end

function DBMMgr:start(battleController,battleId, myUnitId)
	self:clear()
	if not battleId then return end
	--监听技能状态 比如技能吟唱
	self:getCurrentDBMInfosByBattleId(battleId)
	self._myUnitId = myUnitId
    self._battleController = battleController
	battle.NormalSkillFsm:Instance():onTransition(function(skill, fromState, toState)
		local toStateStr = Enums.NormalSkillState[toState]
		if toStateStr == "chant" and UD.setting:isShowDBM() then
			local targetId = Skill_targetId(skill)
			local skillId = Skill_id(skill)
            --需要判断自己是否在技能范围内 若目标不是自己 但是自己在范围内也需要显示提示
            local isMe = self._myUnitId == targetId
            if not isMe then
                isMe = self._battleController:isTargetInSkillRange(skill,self._myUnitId)
            end
            --print(targetId,skillId, isMe)

            --if Skill_getIsMarkTarget(skill) then
            	--有地上红圈啊的技能 需要判断自己是否在红圈内
            	-- 但是此时是技能刚进入吟唱的时候触发 需要找另外一个事件 吟唱中 一直判断自己的位置是否在标记区间
            
            --else
				self:onSkillSing(skillId, isMe)
            --end
		end
	end)
end

function DBMMgr:onSkillSingMarkTarget(targetId,skill)
	if targetId == self._myUnitId then
		local skillId = Skill_id(skill)
		self:onSkillSing(skillId, true)
	end
end


--显示tips tips内容 持续时间 tipsCD
function DBMMgr:_showDBMTips(tipsContent, tipsDuration)
	self:removeTips()

    self._dbmTips = cc.CSLoader:createNode(Res.DBMTipsNode,false,true)
    display.setCascadeOpacityEnabled(self._dbmTips,true)
    self._dbmTips:setPosition(0, display.ui_height - self._rootNode:getPositionY())
	self._dbmTips:findChild("Panel/Panel_tips/text"):setString(L(tipsContent))
    self._dbmTips:findChild("Panel/text_top"):setString(L(tipsContent))
    self._rootNode:addChild(self._dbmTips)
	local timeLine = self._dbmTips:getTimeline()
	timeLine:gotoFrameAndPause(0)

    --local info = timeLine:getAnimationInfo(OPEN_ANI_NAME)
    --local openDuration = info.endIndex - info.startIndex


    local info = timeLine:getAnimationInfo(CLOSE_ANI_NAME)
    local closeDuration = info.endIndex - info.startIndex

    timeLine:play(OPEN_ANI_NAME, false)

    local totalTime = tipsDuration/1000 - closeDuration/60 - STAY_TIME
    if totalTime < 0 then
        totalTime = 0
    end

    local action = cc.Sequence:create(cc.DelayTime:create(STAY_TIME),cc.CallFunc:create(
		function()
			--延迟时间到了之后需要播放本身自带的动画
            timeLine:play(CLOSE_ANI_NAME, false)
        end), cc.DelayTime:create(totalTime),
        cc.CallFunc:create(
            function()
                --延迟时间到了之后需要播放本身自带的动画
                self:removeTips()
            end)
    )
	self._dbmTips:runAction(action)
end

function DBMMgr:removeTips()
	if not cc.isDead(self._dbmTips) then
		self._dbmTips:removeFromParent()
		self._dbmTips = nil
	end
end

--根据CD来判断是否可以播放该DBM
--dbmId 是表的字段
--返回值 bool
function DBMMgr:judgeCDIsOk(dmbId, tipsCD)
	local prePlayTime = self._dbmCDTabel[dmbId] --上一次播放时间
	if not prePlayTime then return true end --若没有播放过

	local curTime = app.session:getServerTime() * 1000 --因为是毫秒
	local deltaTime = curTime - prePlayTime

	return deltaTime >= tipsCD
end

--外部调用
function DBMMgr:startPlayDBM(dbmId, delayTime, tipsCD, tipsContent, tipsDuration)
	if self._rootNode and self:judgeCDIsOk(dbmId, tipsCD) then
        if self._cronsIdx then
            scheduler.cancelCron(self._cronsIdx)
            self._cronsIdx = nil
        end

        self._cronsIdx = scheduler.newCron(function()
            --播放的时候将数据插入
            local curTime = app.session:getServerTime() * 1000 --因为是毫秒
            self._dbmCDTabel[dbmId] = curTime

            self:_showDBMTips(tipsContent, tipsDuration)
        end, delayTime/1000)
	end
end

--根据战斗id从表中拿到所有的这一场战斗用的dbm数据 战斗开始的时候调用
function DBMMgr:getCurrentDBMInfosByBattleId(battleId)
	self._curBattleDBMs = GD:getDBMsByBattleId(battleId)
end

--战斗开始的时候触发
function DBMMgr:onBattleStart()
	if self._curBattleDBMs then
		for k,v in pairs(self._curBattleDBMs) do
			if tonumber(v.tipsTime) == TipsTimeEnum.BattleStart then
				local delayTime = tonumber(v.parameter)
				self:startPlayDBM(v.ID, delayTime, tonumber(v.tipsCD), tostring(v.tipsContent), tonumber(v.tipsDuration))
			end
		end
	end
end

--技能吟唱的时候触发
--inTarget 代表我是否是目标
function DBMMgr:onSkillSing(skillId, isMeInTarget)
	if self._curBattleDBMs then
		for k,v in pairs(self._curBattleDBMs) do
			if tonumber(v.tipsTime) == TipsTimeEnum.SingSkill then
				if tonumber(v.parameter) == skillId then
					if tonumber(v.tipsTarget) == 1 or isMeInTarget then
						self:startPlayDBM(v.ID, 0, tonumber(v.tipsCD), tostring(v.tipsContent), tonumber(v.tipsDuration))
					end
				end
			end
		end
	end
end

--Entity受到技能效果或者buff效果的时候触发
function DBMMgr:onSkillOrBuff(skillOrBuffId, targetId)
	if self._curBattleDBMs then
		for k,v in pairs(self._curBattleDBMs) do
			if tonumber(v.tipsTime) == TipsTimeEnum.InSkill or tonumber(v.tipsTime) == TipsTimeEnum.InBuff then
				if tonumber(v.parameter) == skillOrBuffId then
					if tonumber(v.tipsTarget) == 1 or self._myUnitId == targetId then
						--代表全体
						self:startPlayDBM(v.ID, 0, tonumber(v.tipsCD), tostring(v.tipsContent), tonumber(v.tipsDuration))
					end
				end
			end
		end
	end
end

--Entity血量达到指定值的时候触发
function DBMMgr:onHp(entityTid, hp)
	if self._curBattleDBMs then
		for k,v in pairs(self._curBattleDBMs) do
			if tonumber(v.tipsTime) == TipsTimeEnum.Hp then
				local strs = string_split(v.parameter,"|")
				local eId = tonumber(strs[1])
				local hpPercent = tonumber(strs[2])
				if eId == entityTid and hp <= hpPercent then
					self:startPlayDBM(v.ID, 0, tonumber(v.tipsCD), tostring(v.tipsContent), tonumber(v.tipsDuration))
				end
			end
		end
	end
end

return DBMMgr